package Network;

import chataudio.Constant;
import controleur.AbstractChatControleur;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import model.Connection;

/**
 * La classe ClientTCP sert à lancer une requete TCP<br>
 * @author Romain Bustos
 * @author Matthieu Perrin
 * @version 1.0
 */
public class ClientTCP extends Thread {
    
    Connection request;
    Connection answer;
    AbstractChatControleur controleur;
    private  ObjectOutputStream oos = null;
    private  ObjectInputStream ois = null;
    
    /**
    *<b>Constructeur ClientTCP</b>
    * @param Connection, AbstractChatControleur
    */
    public ClientTCP(Connection conn, AbstractChatControleur controleur){
        this.controleur = controleur;
        this.request = conn;        
    }
    
   @Override
   public void run() {
       SendRequest();
   }
    
    /**
    *<b>Methode SendRequest</b>
    * Envoie une conection contenant un status
    */
   public void SendRequest() {
      try {
        OpenConnection();
        sendData();
        
         if (request.getState() == Constant.Status.SEND) {
              //Lecture de la reponse du serveur distant
              answer = new Connection((Connection) ois.readObject(),controleur);

              //On récupère la reponse
              anlyseAnswer(answer);

              System.out.println("The new Connection Object is: " + answer.toString());
          }
        
        closeConnection();

      } 
      catch(IOException e) {
        System.out.println(e.getMessage());
         System.out.println(e.toString());
        JFrame frame = new JFrame();
        JOptionPane.showMessageDialog(frame,
        "Erreur lors de la connexion au client: " + request.getAdresse() +" \n" + e.toString(),
        "Erreur 0xEB34",
        JOptionPane.ERROR_MESSAGE);
        controleur.removeConnToWaitList(request);
      }
      catch(ClassNotFoundException c){
          
      }
   }

    /**
    *<b>Methode OpenConnection</b>
    * Creation de la socket pour l'envoie
    */
   public void OpenConnection() throws IOException{
       // Ouvre un nouveau socket
       
        //Socket socket = new Socket(request.getAdresse(), 4000);
        Socket socket = new Socket();
        socket.setSoTimeout(1000);
        SocketAddress sa = new InetSocketAddress(request.getAdresse(), Constant.tcpPort);
        socket.connect(sa, 300);
        
        // Ouverture des I/O 
        oos = new ObjectOutputStream(socket.getOutputStream());
        ois = new ObjectInputStream(socket.getInputStream());
   }
   
    /**
    *<b>Methode sendData</b>
    * Ecriture dans la socket si besoin de repondre
    */
   public void sendData() throws IOException{
        //Envoi des données
        oos.writeObject(request);
        oos.flush();
   }
   
    /**
    *<b>Methode nouveau</b>
    * Methode apppelé lors de la demande d'une nouvelle conection
    * à l'hote distant
    */
   public void nouveau(){
        request.setState(Constant.Status.SEND);
        SendRequest();
    }
   
    /**
    *<b>Methode setAccepted</b>
    * Methode apppelé lors de l'acceptation d'une invitation
    * à l'hote distant
    */
   public void setAccepted(){
       request.setState(Constant.Status.ACCEPTED);
       SendRequest();
   }
   
   public void setRefused(){
       request.setState(Constant.Status.REFUSED);
       SendRequest();
   }
   
   public void setPortUDP(){
       request.setState(Constant.Status.NETWORK);
       request.setportEnvoieUDP(controleur.getPortUDP());
       SendRequest();
   }
    
    private void anlyseAnswer(Connection answer) throws IOException
    {
        if (answer.getState() == Constant.Status.WAITING_FOR_RESPONSE){
            controleur.setUserToConn(answer.getID(), answer.getUser());
            controleur.AddConnToWaitList(answer);
        }else if (answer.getState() == Constant.Status.ACCEPTED){
            
        }else if (answer.getState() == Constant.Status.REFUSED){
            
        }
        
        //oos.writeObject(answer);
        //oos.flush();
    }
    
    
    public void arret()
    {
        request.setState(Constant.Status.STOP);
        SendRequest();
    }
    
    private void closeConnection() throws IOException{
        oos.close();
        ois.close();
    }
    
}
